﻿using System.Linq.Expressions;
using Basic.FlowDAL;
using Basic.FlowModel;
using Basic.FlowModel.AuditLogItem;
using Basic.FlowModel.DB;
using Basic.FlowRemoteModel;
using WeDonekRpc.Helper;

namespace Basic.FlowCollect.lmpl
{
    internal class FlowAuditItemLogCollect : IFlowAuditItemLogCollect
    {
        public static readonly FlowAuditItemStatus[] _status = new FlowAuditItemStatus[]
        {
                FlowAuditItemStatus.审核通过,
                FlowAuditItemStatus.审核进行中
         };
        private readonly IFlowAuditItemLogDAL _BasicDAL;
        public FlowAuditItemLogCollect ( IFlowAuditItemLogDAL basicDAL )
        {
            this._BasicDAL = basicDAL;
        }
        public StayRunAuditItem[] GetStayRunItem ()
        {
            return this._BasicDAL.Gets<StayRunAuditItem>(a => a.Status == FlowAuditItemStatus.待开始 && a.StartTime <= DateTime.Now);
        }
        public void CheckIsAccredit ( long logId, long empId )
        {
            if ( !this._BasicDAL.IsExists(c => c.LogId == logId && c.EmpId == empId && _status.Contains(c.AuditState)) )
            {
                throw new ErrorException("flow.audit.emp.no.accredit");
            }
        }
        public Result[] GetItems<Result> ( long logId, Expression<Func<DBFlowAuditItemLog, Result>> selector )
        {
            return this._BasicDAL.Gets(a => a.LogId == logId && _status.Contains(a.AuditState), selector);
        }
        public Result[] GetsByOptItemId<Result> ( long itemId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.OptItemId == itemId);
        }

        public Result[] GetsByLogId<Result> ( long logId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.LogId == logId);
        }
        public long[] GetInProgress ( long[] subsId )
        {
            return this._BasicDAL.Gets(a => subsId.Contains(a.RootNodeId) && a.Status == FlowAuditItemStatus.审核进行中, a => a.Id);
        }
        public Result[] GetItemLog<Result> ( long logId, long nodeId ) where Result : class, new()
        {
            return this._BasicDAL.GetItemLog<Result>(logId, nodeId);
        }
        public Result Get<Result> ( long itemId ) where Result : class, new()
        {
            return this._BasicDAL.Get<Result>(itemId);
        }

        public long[] GetNodeAuditEmpId ( long logId, long rootNodeId, long nodeId )
        {
            long batchId = this._BasicDAL.Get(a => a.LogId == logId && a.NodeId == nodeId && a.RootNodeId == rootNodeId && a.Status == FlowAuditItemStatus.审核通过, a => a.BatchNo, "EndTime desc");
            if ( batchId == 0 )
            {
                return null;
            }
            return this._BasicDAL.Gets(a => a.LogId == logId && a.BatchNo == batchId, a => a.EmpId);
        }
        public long[] GetNodeAuditEmpId ( long logId, long rootNodeId, long[] nodeId )
        {
            return this._BasicDAL.GetNodeAuditEmpId(logId, rootNodeId, nodeId);
        }
        public Result[] Gets<Result> ( long logId, long nodeId, long backNo ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.LogId == logId && a.NodeId == nodeId && a.BatchNo == backNo);
        }
        public Result[] Gets<Result> ( long logId, long nodeId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.LogId == logId && a.NodeId == nodeId);
        }
        public long[] GetRunNodeId ( long logId, long rootBatchNo, int lvl )
        {
            return this._BasicDAL.Gets<long>(a => a.LogId == logId && a.RootBatchNo == rootBatchNo && a.Status == FlowAuditItemStatus.审核进行中 && a.NodeLvl >= lvl, a => a.NodeId);
        }
        public Result[] GetGoByNode<Result> ( long rootBatchNo, long[] nodeId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => a.RootBatchNo == rootBatchNo && nodeId.Contains(a.NodeId) && ConstDic.GoByNodeStatus.Contains(a.AuditState) && ConstDic.GoByNodeMark.Contains(a.MarkState), "CreateTime desc");
        }

        public Result[] Gets<Result> ( IEnumerable<long> ids ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => ids.Contains(a.Id));
        }
        public Result[] GetRunItems<Result> ( long[] logId ) where Result : class, new()
        {
            return this._BasicDAL.Gets<Result>(a => logId.Contains(a.LogId) && a.Status == FlowAuditItemStatus.审核进行中);
        }
        public AuditItemLog GetAuditLog ( long itemId )
        {
            AuditItemLog log = this._BasicDAL.GetAuditLog(itemId);
            if ( log == null )
            {
                throw new ErrorException("flow.audit.log.not.find");
            }
            return log;
        }

        public TimeOutLogItem[] GetTimeOuts ()
        {
            return this._BasicDAL.Gets<TimeOutLogItem>(a => a.Status == FlowAuditItemStatus.审核进行中 && a.TimeOut != null && a.TimeOut < DateTime.Now);
        }
    }
}
